package com.campus.help.utils;

import com.campus.help.config.FileStorageConfig;
import com.campus.help.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * 本地文件存储工具类
 *
 * @author campus-help
 * @since 2025-10-25
 */
@Slf4j
@Component
public class FileStorageUtils {

    @Autowired
    private FileStorageConfig fileStorageConfig;

    /**
     * 上传文件
     * 
     * @param file 文件
     * @param folder 文件夹名称（如：images、banners）
     * @return 相对路径（如：images/2025/10/25/uuid.jpg）
     */
    public String uploadFile(MultipartFile file, String folder) {
        try {
            if (file.isEmpty()) {
                throw new BusinessException("文件不能为空");
            }

            // 获取原始文件名和扩展名
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null || originalFilename.isEmpty()) {
                throw new BusinessException("文件名不能为空");
            }
            
            String extension = "";
            int lastDotIndex = originalFilename.lastIndexOf(".");
            if (lastDotIndex > 0) {
                extension = originalFilename.substring(lastDotIndex);
            }

            // 构建存储路径：folder/年/月/日/uuid.ext
            LocalDate now = LocalDate.now();
            String datePath = now.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
            String relativePath = folder + "/" + datePath;
            
            // 生成唯一文件名
            String fileName = UUID.randomUUID().toString() + extension;
            String relativeFilePath = relativePath + "/" + fileName;
            
            // 创建完整的物理路径
            String uploadPath = fileStorageConfig.getUploadPath();
            if (uploadPath == null || uploadPath.isEmpty()) {
                throw new BusinessException("文件存储路径未配置");
            }
            
            Path fullPath = Paths.get(uploadPath, relativePath);
            
            // 确保目录存在
            Files.createDirectories(fullPath);
            
            // 保存文件
            Path targetPath = fullPath.resolve(fileName);
            file.transferTo(targetPath.toFile());
            
            log.info("文件上传成功：{}", relativeFilePath);
            return relativeFilePath;
            
        } catch (IOException e) {
            log.error("文件上传失败：{}", e.getMessage(), e);
            throw new BusinessException("文件上传失败：" + e.getMessage());
        }
    }

    /**
     * 获取文件访问URL
     * 
     * @param relativePath 相对路径
     * @return 完整的访问URL
     */
    public String getFileUrl(String relativePath) {
        if (relativePath == null || relativePath.isEmpty()) {
            throw new BusinessException("文件路径不能为空");
        }
        
        String accessUrlPrefix = fileStorageConfig.getAccessUrlPrefix();
        if (accessUrlPrefix == null || accessUrlPrefix.isEmpty()) {
            throw new BusinessException("文件访问URL前缀未配置");
        }
        
        // 确保URL前缀以/结尾
        if (!accessUrlPrefix.endsWith("/")) {
            accessUrlPrefix += "/";
        }
        
        // 确保相对路径不以/开头
        if (relativePath.startsWith("/")) {
            relativePath = relativePath.substring(1);
        }
        
        String fileUrl = accessUrlPrefix + relativePath;
        log.debug("生成文件访问URL：{}", fileUrl);
        return fileUrl;
    }

    /**
     * 删除文件
     * 
     * @param relativePath 相对路径
     */
    public void deleteFile(String relativePath) {
        try {
            if (relativePath == null || relativePath.isEmpty()) {
                log.warn("文件路径为空，跳过删除");
                return;
            }
            
            String uploadPath = fileStorageConfig.getUploadPath();
            if (uploadPath == null || uploadPath.isEmpty()) {
                log.warn("文件存储路径未配置，跳过删除");
                return;
            }
            
            Path filePath = Paths.get(uploadPath, relativePath);
            File file = filePath.toFile();
            
            if (file.exists()) {
                if (file.delete()) {
                    log.info("文件删除成功：{}", relativePath);
                } else {
                    log.warn("文件删除失败：{}", relativePath);
                }
            } else {
                log.warn("文件不存在，无需删除：{}", relativePath);
            }
            
        } catch (Exception e) {
            log.error("文件删除失败：{}", e.getMessage(), e);
            // 不抛出异常，避免影响业务流程
        }
    }

    /**
     * 检查文件是否存在
     * 
     * @param relativePath 相对路径
     * @return 是否存在
     */
    public boolean fileExists(String relativePath) {
        try {
            if (relativePath == null || relativePath.isEmpty()) {
                return false;
            }
            
            String uploadPath = fileStorageConfig.getUploadPath();
            if (uploadPath == null || uploadPath.isEmpty()) {
                return false;
            }
            
            Path filePath = Paths.get(uploadPath, relativePath);
            return Files.exists(filePath);
            
        } catch (Exception e) {
            log.error("检查文件是否存在失败：{}", e.getMessage(), e);
            return false;
        }
    }
}

